Objektumok használata ORACLE-ben
Objektumok használata hasonló okokból ajánlott, mint minden más fejlesztői környezetben. A sok egyéb előnye mellett komplexebb, többször felhasználható komponenseket készíthetünk. Emellett kívülről, pl. egy JAVA nyelven megírt alkalmazásból egy Oracle objektumot (annak attribútumait vagy eljárásait) könnyen meg lehet hívni. Továbbá az objektumok használata a teljesítményt is fokozza, ahogy lentebb látni fogjuk, például egy collection-be helyezve az objektumokat elemeit, a memóriában futtatva jóval gyorsabban tudunk egy folyamatot lefuttatni, mintha direkt táblából olvasnánk, vagy temp táblába ínánk.
Pár példa a használatára:
Hasznos tud lenni az adatbázisok létrehozásakor. Ha például több adatbázis táblában szeretnénk ugyanolyan mezőket eltárolni (pl. a customers tábla egyéb adatok mellett a vásárlók címét, irányítószámát tartalmazza, ugyanígy a vendor tábla egyebek mellett a telephelyek címét, irányítószámát tartalmazza), akkor a táblák létrehozásakor elegendő az objektumot meghivatkozni:
create or replace type address as object (Egy új objektum létrehozását többek között a következő módon tudjuk megtenni. A fentebb létrehozott address-ből konstruktor használatával (ahol a konstruktornak átadjuk az értékeket, amely értékekkel az új objektumot létrehozzuk):
Streetno varchar2(20),
City varchar2(20),
ZIP varchar2(20));
create table vendors (vendor_name varchar2(20),
Vendor_addr address);
create table customers (customer_name varchar2(20),
Customer_addr address);
DECLAREObject Type létrehozásakor nem csak a fenti példában látható attribútumokat hozhatunk létre, hanem metódusokat is, amelyek az objektum létrehozásakor futnak le attól függően, hogy milyen értékeket adunk át neki. Az alábbiban egy CONSTRUCTOR FUNCTION-t hozunk létre, ahol egy üres konstruktort hozunk létre - ennek eredményeképpen egy üres objektumot kapunk aztán vissza:
v_address address;
BEGIN
v_address := address('Fő utca', 'Budapest', '2024');
DBMS_OUTPUT.PUT_LINE(v_address.Streetno || ', ' || v_address.City || ', ' || v_address.ZIP);
END;
create or replace type address as object (Ehhez kapcsolódóan létre kell hoznunk a TYPE BODY-t is, ahol az objektum eljárásait kell definiálnunk:
Streetno varchar2(20),
City varchar2(20),
ZIP varchar2(20),
CONSTRUCTOR FUNCTION address
RETURN SELF AS RESULT );
create or replace type body address ASEgy új objektumot úgy tudunk ebből létrehozni, hogy a konstruktornak nem adunk át értéket, viszont az értékeket manuálisan hozzuk létre:
CONSTRUCTOR FUNCTION address
RETURN SELF AS RESULT
AS BEGIN
RETURN;
END;
END;
DECLAREAz alábbiakban a fentit kiegészítjük, itt már átadunk a konstruktornak értékeket, és az annak átadott értéket kapja meg az új objektum:
v_address address := address();
BEGIN
v_address.Streetno : = 'Fő utca';
v_address.City := 'Budapest';
v_address.ZIP := '1024';
DBMS_OUTPUT.PUT_LINE(v_address.Streetno || ', ' || v_address.City || ', ' || v_address.ZIP);
END;
create or replace type address as object (Amiben nagyon hasznos tud lenni az object type, az a COLLECTION-ök használata. Egy collection-ben el tudjuk tárolni a létrehozott objektumokat, amelyet aztán könnyen ki tudunk iratni, vagy be tudjuk tenni egy adattáblába, vagy más műveleteket tudunk rajtuk futtatni. Ezzel a módszerrel sokkal gyorsabban tudunk végigmenni az adatokon, mintha adattáblából kérdeznénk le azokat. Első körben hozzunk létre egy collection-t a fenti objektumból:
Streetno varchar2(20),
City varchar2(20),
ZIP varchar2(20),
CONSTRUCTOR FUNCTION address
RETURN SELF AS RESULT
CONSTRUCTOR FUNCTION address(Streetno VARCHAR2, City varchar2, ZIP varchar2)
RETURN SELF AS RESULT );
create or replace type body address AS
CONSTRUCTOR FUNCTION address
RETURN SELF AS RESULT
AS BEGIN
RETURN;
END;
CONSTRUCTOR FUNCTION address (Streetno VARCHAR2, City varchar2, ZIP varchar2)
RETURN SELF AS RESULT
AS BEGIN
SELF.Streetno := Streetno;
SELF.City := City;
SELF.ZIP := ZIP;
RETURN;
END;
END;
DECLARE
v_address address := address('Fő utca', 'Budapest', '1024');
BEGIN
DBMS_OUTPUT.PUT_LINE(v_address.Streetno || ', ' || v_address.City || ', ' || v_address.ZIP);
END;
CREATE OR REPLACE TYPE address_a AS TABLE OF address;Ezzel létrehoztunk egy collection-t, amiben az address objektumok értékeit fogjuk eltárolni.
DECLAREEzzel létrehoztunk két objektumot, azokat eltároltuk a collection-ben. Hatékony módszer a BULK COLLECT INTO-val való történő beolvasás a collection-be:
v_address_a address_a := address_a();
BEGIN
v_address_a.EXTEND; -- ezzel létrehozunk egy új elemet a collection-ben
v_address_a(1) := address('Fő utca', 'Budapest', '1024'); -- az első elem értékei
v_address_a.EXTEND; -- ezzel létrehozunk egy második elemet a collection-ben
v_address_a(2) := address('Alsó utca', 'Érd', '2030'); -- a második elem értékei
END;
DECLAREA collection tartalmára aztán egyéb üzleti feldolgozást lehet építeni. Még egy példa a teljes folyamatra:
v_address_a address_a;
BEGIN
SELECT address(Streetno, City, ZIP)
BULK COLLECT INTO v_address_a
FROM table_address;
END;
1. lépésben collection létrehozása (ide tesszük majd be az objektumok elemeit):
DECLARE2. lépésben: OBJECT TYPE és OBJECT TYPE BODY létrehozása, ezzel hozzuk majd létre magukat az objektumokat:
create or replace TYPE "OUT_TYPE" AS table of NUMBER(20,5);
DECLARE3. lépésben egy eljárásban meghívjuk az OBJECT TYPE-ot:
create or replace TYPE "J_SZEKT_SEMAMUTATOK" AS OBJECT (
P_11 NUMBER(20,0),
P_118 NUMBER(20,0),
STATIC FUNCTION getNull(J_SEMA J_SZEKT_SEMAMUTATOK)
RETURN J_SZEKT_SEMAMUTATOK );
create or replace TYPE BODY "J_SZEKT_SEMAMUTATOK" AS
STATIC FUNCTION getNull(J_SEMA J_SZEKT_SEMAMUTATOK)
RETURN J_SZEKT_SEMAMUTATOK AS v_j J_SZEKT_SEMAMUTATOK;
BEGIN
v_j:=J_SZEKT_SEMAMUTATOK
(0,-- P_11 ,
0,-- P_118 ); -- itt adunk alapvetően 0 értékeket minden mezőnek
RETURN v_j;
END getNull;
END;
create or replace PACKAGE BODY "J_A_HITEL_T" as4. lépésben a folyamat elején létrehozott collection-be beillesztjük az objektumokat:
v_j j_szekt_semamutatok;
PROCEDURE HITELINTEZET AS
BEGIN
v_j := j_szekt_semamutatok.getnull(v_j); --első körben a getNull funnction: minden mező 0 értéket kap
-- innentől pedig minden attribútumnak kiszámítunk egy értéket üzleti logika szerint:
v_j.p_11 := 256;
J_SZEKT_EVES_T.FELTOLT('P_11', v_j.p_11);
v_j.p_118 := v_j.p_11 * 3.14;
J_SZEKT_EVES_T.FELTOLT('P_118', v_j.p_118);
PROCEDURE FELTOLT (v_mutato_nev VARCHAR2, v_ertek NUMBER) AS5.lépésben a collection elemeit végül egy táblába betöltjük
BEGIN
v1.extend(2); -- 2 db. mutatót hoztunk létre az OBJECT TYPE-ban
v1(v_mutato_nev) := v_ertek;
END;
PROCEDURE FELTOLT_TABLABA ASNagy vonakakban az objektumokról ennyi, persze még millió lehetőség rejlik benne, de ha a gyorsaságot, egyszerűséget tartjuk szem előtt, akkor ezekkel az alapokkal már el lehet boldogulni.
BEGIN
v1.extend(2);
FOR i IN 1..c_db LOOP
INSERT INTO table_name VALUES (v1(i));
END LOOP;
END;